package com.fzj.charging.device.dao.repository.impl;

import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.C;
import com.fzj.charging.device.dao.repository.StationRedisRepository;
import com.fzj.charging.device.pojo.entity.ChargingStation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.BoundGeoOperations;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository("geoAndMapOne")//用一个map存储所有的场站基本信息
public class StationRedisGeoAndMapOneRepositoryImpl implements StationRedisRepository {
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public void saveStationLocation(List<ChargingStation> chargingStationList) {

        HashMap<Integer, Point> stationGeoMap = new HashMap<>();
        HashMap<Integer, ChargingStation> stationInfoMap = new HashMap<>();
        if(chargingStationList!=null&&!chargingStationList.isEmpty()){
            String bigKey = "station_info";
            for (ChargingStation chargingStation : chargingStationList) {
                BigDecimal stationLng = chargingStation.getStationLng();
                BigDecimal stationLat = chargingStation.getStationLat();
                Point point = new Point(new Double(String.valueOf(stationLng)),new Double(String.valueOf(stationLat)) );
                stationGeoMap.put(chargingStation.getId(),point);

                stationInfoMap.put(chargingStation.getId(),chargingStation);
            }
            BoundGeoOperations boundGeoOperations = redisTemplate.boundGeoOps("station_geo");
            boundGeoOperations.add(stationGeoMap);
            HashOperations hashOperations = redisTemplate.opsForHash();
            hashOperations.putAll(bigKey,stationInfoMap);
        }


    }

    @Override
    public List<ChargingStation> selectStation(Double lng, Double lat, Double distance) {
        Circle circle = getCircle(lng, lat, distance);
        BoundGeoOperations boundGeoOperations = redisTemplate.boundGeoOps("station_geo");
        GeoResults<RedisGeoCommands.GeoLocation<Integer>> geoResults = boundGeoOperations.radius(circle);

        HashOperations<String,Integer,ChargingStation> hashOperations = redisTemplate.opsForHash();
        ArrayList<ChargingStation> stationList = new ArrayList<>();
        for (GeoResult<RedisGeoCommands.GeoLocation<Integer>> geoResult : geoResults) {
            Integer stationId = geoResult.getContent().getName();
            ChargingStation chargingStation = hashOperations.get("station_info", stationId);
            stationList.add(chargingStation);
        }
        return stationList;
    }

    public Circle getCircle(Double lng, Double lat, Double distance){
        Point point = new Point(lng, lat);
        Distance geoDistance = new Distance(distance, Metrics.KILOMETERS);
        return new Circle(point,geoDistance);
    }
}
